package com.chat;

import com.chat.handler.ChatClientHandler;
import com.chat.handler.HeartBeatClientHandler;
import com.netty.imp.IMPDecoder;
import com.netty.imp.IMPEncoder;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;

/**
 * 完成Java控制台输入与服务端的交互逻辑
 *
 * @author kewei
 */
public class ChatClient {

    public static void main(String[] args) {
        new ChatClient("张三").connect("127.0.0.1", 8080);
    }

    private ChatClientHandler chatClientHandler;

    private HeartBeatClientHandler heartBeatClientHandler;

    private String host;

    private int port;

    public ChatClient(String nickName) {
        this.chatClientHandler = new ChatClientHandler(nickName);
        this.heartBeatClientHandler = new HeartBeatClientHandler(nickName);
    }

    public void connect(String host, int port) {
        this.host = host;
        this.port = port;
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.
                    group(workerGroup).
                    channel(NioSocketChannel.class).
                    option(ChannelOption.SO_KEEPALIVE, true).
                    handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            pipeline.addLast(new LengthFieldBasedFrameDecoder(61440, 0, 2, 0, 2));
                            pipeline.addLast(new IMPDecoder());
                            pipeline.addLast(new LengthFieldPrepender(2));
                            pipeline.addLast(new IMPEncoder());
                            pipeline.addLast(heartBeatClientHandler);
                            pipeline.addLast(chatClientHandler);
                        }
                    });
            ChannelFuture future = bootstrap.connect(this.host, this.port).sync();
            future.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            workerGroup.shutdownGracefully();
        }
    }
}
